package com.mldong.wxauth.exception;


import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.mldong.wxauth.base.CommonError;
import com.mldong.wxauth.base.CommonResult;
import com.mldong.wxauth.base.GlobalErrEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.stream.Collectors;

/**
 * 全局异常处理类
 * @author mldong
 *
 */
@ControllerAdvice
public class DefaultExceptionHandler {

   private static Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class);
   /**
    * 服务层异常
    * @param e
    * @return
    */
   @ExceptionHandler(BizException.class)
   @ResponseBody
   public CommonResult<?> serviceExceptionHandler(BizException e) {
       log.error("服务层异常:", e);
       return CommonResult.error(e.getError());
   }
   /**
    * json转换异常，一般为自定义枚举类转换出问题
    * @param e
    * @return
    */
   @ExceptionHandler(HttpMessageConversionException.class)
   @ResponseBody
   public CommonResult<?> invalidDefinitionExceptionHandler(HttpMessageConversionException e) {
       log.error("json转换异常:", e);
       if(e.getCause().getClass().isAssignableFrom(InvalidFormatException.class)) {
           // 如果是InvalidFormatException
           final InvalidFormatException invalidFormatException = (InvalidFormatException) e.getCause();
           // Class<?> clazz = invalidFormatException.getTargetType();

           return CommonResult.error(new CommonError() {

               @Override
               public int getValue() {
                   return GlobalErrEnum.GL99990100.getValue();
               }

               @Override
               public String getName() {
                   return invalidFormatException.getMessage();
               }
           },null);
       }
       return CommonResult.fail();
   }

   /**
    * 控制层参数校验异常
    * @param e
    * @return
    */
   @ExceptionHandler(MethodArgumentNotValidException.class)
   @ResponseBody
   public CommonResult<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e){
       log.error("参数校验异常:{}", e.getMessage());
       final String errorMsg = String.join(",", e.getBindingResult().getAllErrors().stream().map(item->{
           return item.getDefaultMessage();
       }).collect(Collectors.toList()));
       return CommonResult.error(new CommonError() {

           @Override
           public int getValue() {
               return GlobalErrEnum.GL99990100.getValue();
           }

           @Override
           public String getName() {
               return errorMsg;
           }
       });
   }
   /**
    * 其他异常
    * @param e
    * @return
    */
   @ExceptionHandler(Exception.class)
   @ResponseBody
   public CommonResult<?> excetionHandler(Exception e){
       if(e.getClass().getName().equals("org.springframework.security.oauth2.common.exceptions.InvalidGrantException")) {
           log.error("refresh_token凭证异常:", e);
           if(e.getMessage().contains("Invalid refresh token")) {
               return CommonResult.error(GlobalErrEnum.GL99991015);
           } else if(e.getMessage().contains("用户名或密码错误")||e.getMessage().contains("Bad credentials")) {
               return CommonResult.error(GlobalErrEnum.GL99991016);
           } else {
               return CommonResult.error(GlobalErrEnum.GL99991099);
           }
       } else if(e.getClass().getName().equals("org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException")) {
           log.error("grant_type:", e);
           return CommonResult.error(GlobalErrEnum.GL99991017);
       } else if (e.getClass().getName().contains("SQL") || e.getClass().getName().contains("Sql")
       || e.getClass().getName().equals("org.springframework.dao.DataIntegrityViolationException")){
           log.error("数据库异常:", e);
           return CommonResult.error(GlobalErrEnum.GL99990100);
       }
       log.error("未捕获异常:", e);
       return CommonResult.fail(e.getMessage(), null);
   }
   /**
    * json转换异常
    * @param e
    * @return
    */
   @ExceptionHandler(HttpMessageNotReadableException.class)
   @ResponseBody
   public CommonResult<?> httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
       log.error("json转换异常:", e);
       return CommonResult.error(new CommonError() {
           @Override
           public int getValue() {
               return GlobalErrEnum.GL99991013.getValue();
           }

           @Override
           public String getName() {
               return e.getMessage();
           }
       });
   }
}
